#include "tcpserver.h"
#define LENGTH_OF_LISTEN_QUEUE 20

TcpServer::TcpServer(int port)
    : port_(port)
    , running_(false)
{
    dataType = new int(0);
}

void TcpServer::start(GetSigns gets, SendSignsType send)
{
    getSigns = gets;
    sendSignsType = send;
    //开启线程池
    ThreadPool threadPool(4);       //定义线程池
    threadPool.setMaxQueueSize(100);
    threadPool.start();

    //客户端套接字
    sServer = socket(PF_INET, SOCK_STREAM, 0);
    if(-1 == sServer) {
        std::cout << "socket failed!" << std::endl;
        return  ;
    }

    //服务器套接字配置
   /* bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容全部设置为0
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htons(INADDR_ANY);
    server_addr.sin_port = htons(port_);

    //创建用于internet的流协议(TCP)socket,用server_socket代表服务器socket
    int server_socket = socket(PF_INET,SOCK_STREAM,0);*/


    addrServ.sin_family = AF_INET;
    addrServ.sin_port = htons(port_);
    addrServ.sin_addr.s_addr = htonl(INADDR_ANY);

    //绑定套接字
    //bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr))
    bindfp = bind(sServer, (struct sockaddr *)&addrServ, sizeof(addrServ));
    if(-1 == bindfp) {
        std::cout << "bind failed! " << strerror(errno) << std::endl;
        close(sServer);                     //关闭套接字
        return ;
    }
    else {
        std::cout << "bind success!" << std::endl;
    }

    //开始监听
    retVal = listen(sServer, LENGTH_OF_LISTEN_QUEUE);
    if(-1 == retVal) {
        std::cout << "listen failed!" << std::endl;
        close(sServer);             //关闭套接字
        close(bindfp);               //关闭绑定
        return  ;
    }
    else {
        std::cout << "listen success! port: " << addrServ.sin_port << std::endl;
    }

    //开始运行
    running_ = true;
    while (1) {
        socklen_t addrClientlen = sizeof(sockaddr_in);
        int sClient;
        //接受客户端请求
        sClient = accept(sServer, (sockaddr *)&addrClient, &addrClientlen);
        if(-1 == sClient) {
            std::cout << "accept failed!" << strerror(errno)  << std::endl;
            close(sServer);             //关闭套接字
            close(bindfp);              //关闭绑定
            break ;
        }
        else {
            std::cout << "Server get connection from "
                      << inet_ntoa(addrClient.sin_addr) << std::endl;
        }

        //创建线程共享数据内存
        client = new int(sClient);
        //创建读线,使用传值形式
        auto ReadData_ = std::bind(&TcpServer::ReadData, *this);
        threadPool.run(ReadData_);
        //创建写线程,使用传值形式
        auto SendData_ = std::bind(&TcpServer::SendData, *this);
        threadPool.run(SendData_);
    }
}

void TcpServer::stop()
{
    std::cout << "Service Stop" << std::endl;
    running_ = false;
    delete dataType;
    close(sServer);                 //关闭套接字
    close(bindfp);                  //关闭绑定
}

void TcpServer::SendData() {
    std::string Data;

    while (*client != -1) {
        /*Data = "S522";
        Data = Prefix + Data;
        std::cout << Data;
        write(*client, Data.c_str(), Data.size());
        Data = Prefix + "B88";
        write(*client, Data.c_str(), Data.size());
        Data = Prefix + "Q300";
        write(*client, Data.c_str(), Data.size());
        Data = Prefix + "T35";
        write(*client, Data.c_str(), Data.size());
        usleep(200000); }*/
        //bzero(buffer, BUFFER_SIZE);
        //length = recv(new_server_socket,buffer,BUFFER_SIZE,0);
        Data.clear();

        if (getSigns(Data) == -1) {
            std::cout << "Read signs error" << strerror(errno) <<std::endl;
            break;
        }
        /*if (getSigns(Data) == 0) {
            break;
        }*/

            //Data = '2' + Data;
            std::cout << Data;
            send(*client, Data.c_str(), Data.size(), 0);

    }
    delete client;
    //delete dataType;
}

void TcpServer::ReadData()
{
    char buf[BUF_SIZE] = {0};  //客户端套接字
    int nread;

    //如果客户端不关闭
    while ( (nread = read(*client,buf,BUF_SIZE) ) != 0 ) {
        if(nread == -1) {
            std::cout << "Read Error:" << strerror(errno) << std::endl;
            break;
        }

        std::string tmp = "";
        time_t t;

        tmp += buf;
        time(&t);
        std::cout << ctime(&t) << "  Receive data from the client：" << tmp << *client << std::endl;

        //char parametes[20020] = "name=";
        std::string Data;
        if(tmp == "heart") {
            *dataType ^=  HEART;

            if (*dataType & HEART) {
                Data += "Began testing the heart rate.";

                sendSignsType(std::string("1"));
            }
            else{
                Data += "Stop testing the heart rate.";
                sendSignsType(std::string("1"));
            }
        }
        else if(tmp == "temperature") {
            *dataType ^= TEMP;
            if (*dataType & HEART) {
                Data += "Began testing the temperature.";
                sendSignsType(std::string("2"));
            }
            else{
                Data += "Stop testing the temperature.";
                sendSignsType(std::string("2"));
            }
        }
        else {
            Data += "Input Error!!!";
            std::cout << "Input Error"<< std::endl;
        }
        write(*client, Data.c_str(), Data.size());

        //反馈信息给服务器
        /*char api[] = "/wechat/gozillaMessageReciever";
        std::cout << notifyUrl.c_str() << std::endl;
        post_http(notifyUrl.c_str(), api, parametes);*/
        memset(buf, 0, sizeof(buf));
    }

    /* 这个通讯已经结束     */
    std::cout << "Disconnect from " << inet_ntoa(addrClient.sin_addr) << std::endl;
    *client = -1;
    close(*client);
}

TcpServer::~TcpServer(){
    //if (running_) {
        //std::cout << "create id:" << std::this_thread::get_id() << std::endl;
        //stop();
   // }
}


int post_http(const char* hostname, char* api, char* parameters)
{
    int hsocket;
    sockaddr_in saServer;
    hostent * lphostent;
    int     nRet;

    char reqHead[22048] = {0};
    strcat(reqHead, "POST ");
    strcat(reqHead, api);
    strcat(reqHead, " HTTP/1.1\r\n");
    strcat(reqHead, "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, */*\r\n");
    strcat(reqHead, "Referer: http://");
    strcat(reqHead, hostname);
    strcat(reqHead, api);
    strcat(reqHead, "\r\n");
    strcat(reqHead, "Accept-Language: zh-cn\r\n");
    strcat(reqHead, "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; );\r\n");
    strcat(reqHead, "Content-Type: application/x-www-form-urlencoded\r\n");
    strcat(reqHead, "Accept-Encoding: gzip, deflate\r\n");
    strcat(reqHead, "Host: ");
    strcat(reqHead, hostname);
    strcat(reqHead, "\r\n");

    char content_header[100];
    sprintf(content_header,"Content-Length: %lud\r\n", strlen(parameters));
    strcat(reqHead, content_header);

    strcat(reqHead, "Connection: Keep-Alive\r\n");
    strcat(reqHead, "Cache-Control: no-cache\r\n");
    strcat(reqHead, "Cookie: hehhehehe \r\n\r\n");
    strcat(reqHead, parameters);
    strcat(reqHead, "\r\n");

    // 初始化套接字
    //if(WSAStartup(MAKEWORD(2,2),&wsadata))
    //	printf("初始化SOCKET出错！");

    lphostent = gethostbyname(hostname);
    if(lphostent==NULL)
        printf("lphostent为空！");
    hsocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    saServer.sin_family = AF_INET;
    saServer.sin_port = htons(80);
    saServer.sin_addr = *((in_addr *)*lphostent->h_addr_list);
    // 利用SOCKET连接
    nRet = connect(hsocket,(sockaddr *)&saServer,sizeof(sockaddr_in));
    if(nRet == -1)
    {
        printf("建立连接时出错！");
        close(hsocket);
        return 1;
    }
    // 利用SOCKET发送

    nRet = send(hsocket,reqHead,strlen(reqHead),0);
    if(nRet==-1) {
        printf("发送数据包时出错！");
        close(hsocket);
    }

    nRet=1;
    //char   Dest[3000];
    //while(nRet>0)
    //{
    //	// 接收返回数据包
    //	nRet=recv(hsocket,(LPSTR)Dest,sizeof(Dest),0);
    //	if(nRet>0)
    //		Dest[nRet]=0;
    //	else
    //		Dest[0]=0;
    //	// 显示返回数据包的大小、内容
    //	printf("\nReceived   bytes:%d\n",nRet);
    //	printf("Result:\n%s",Dest);
    //}
    return 0;
}

